﻿///////////////////////////////////////////////////////////////////////////////////////////////
// System.Text.Parsing - © 2011 Sebastien Pellizzari
// Released under the MIT License (http://www.opensource.org/licenses/mit-license.php)
///////////////////////////////////////////////////////////////////////////////////////////////

namespace System.Text.Parsing
{
    /// <summary>Represents a token range for text data.</summary>
    public struct TextRange : IDataRange<TextRange>
    {
        private TextLocation _start, _end;

        //-----------------------------------------------------------------------
        //     Properties
        //-----------------------------------------------------------------------

        /// <summary>Gets the location of the beginning of the range.</summary>
        public TextLocation Start { get { return _start; } }
        /// <summary>Gets the location of the end of the range.</summary>
        public TextLocation End { get { return _end; } }

        /// <summary>Gets a <see cref="TextRange"/> value that represents an unknown range.</summary>
        public static TextRange Unknown { get { return new TextRange(TextLocation.Unknown, TextLocation.Unknown); } }

        //-----------------------------------------------------------------------
        //     Constructors
        //-----------------------------------------------------------------------

        /// <summary>Initializes an instance of the <see cref="TextRange"/> class.</summary>
        /// <param name="start">The location of the beginning of the range.</param>
        /// <param name="start">The location of the end of the range.</param>
        public TextRange(TextLocation start, TextLocation end)
        {
            _start = start;
            _end = end;
        }

        /// <summary>Initializes an instance of the <see cref="TextRange"/> class.</summary>
        /// <param name="start">The location of the beginning of the range.</param>
        /// <param name="start">The location of the end of the range.</param>
        public TextRange(ref TextLocation start, ref TextLocation end)
        {
            _start = start;
            _end = end;
        }

        //-----------------------------------------------------------------------
        //     Methods
        //-----------------------------------------------------------------------

        /// <summary>Merges this text range with another range.</summary>
        public void MergeWith(ref TextRange other, out TextRange result)
        {
            TextLocation min, max;
            TextLocation.Min(ref _start, ref other._start, out min);
            TextLocation.Max(ref _end, ref other._end, out max);
            result = new TextRange(ref min, ref max);
        }

        /// <summary>Creates a new range that starts and ends at the end of this range.</summary>
        /// <param name="result">The new range object.</param>
        /// <remarks>The current object must remain unchanged during the operation.</remarks>
        public void GetEndRange(out TextRange result)
        {
            result = new TextRange(ref _end, ref _end);
        }
    }
}
